using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using IQIGame.Onigao.GamePlay;

namespace IQIGame.Onigao.Logic
{
    /// <summary>
    /// 玩家控制的英雄角色传送
    /// 参数组1：1：regionCid，2：传送门唯一tag（-1为手动指定传送位置），3：传送后是否改变旋转，4：传送到目的地后的rotationY
    /// 参数组2：1：position.x，2：position.y，3：position.z（前三个参数在“参数组1里，参数2传送门tag==0”时必须，否则不填，其中position.y如果不确定可填0）
    /// </summary>
    public class ExecTeleport : BaseServiceExecution
    {
        public override void Execute(LevelRegion region, LevelPlayer player)
        {
            var config = _config as ExecParamTeleport;

            int regionCid = config.regionCid;
            int portalTagOrMcid = config.portalTagOrMcid;
            bool isSetRotation = config.isSetRotation;
            int rotationY = config.rotationY;

            if (portalTagOrMcid == -1 && config.position == Vector3Int.zero)
            {
                PrintParamInvalidError();
                return;
            }

            if (regionCid == 0)
            {
                regionCid = region.CfgRegionInstance.Id;
            }
            Vector3Logic position;
            Vector3Logic paramPosition = config.position;
            if (portalTagOrMcid != -1)
            {
                LevelEntity portal = portalTagOrMcid == 0 ? triggerEntity : region.level.GetEntityByTagOrMcid(regionCid, portalTagOrMcid);
                if (portal == null)
                {
                    LogicLog.LogError($"传送失败，找不到实体。regionCid: {regionCid}, 实体tagOrMcid：{portalTagOrMcid}");
                    return;
                }
                if (paramPosition == Vector3Logic.zero) //只填了实体，代表在实体附近找合适的位置传送
                {
                    LgLevelEntityUtil.GetTeleportPos(portal, out position);
                }
                else //实体和位置都填了，代表朝相对于指定实体的指定位置传送
                {
                    position = portal.position + paramPosition; //相对位置
                }
            }
            else //没填实体，只填了位置，代表朝绝对位置传送
            {
                position = paramPosition; //绝对位置
            }

            region.level.EnterRegionAndTeleport(regionCid, player, position);
            player.TriggerBuffService(ServiceTriggerType.TeleportArrive);

            if (isSetRotation)
            {
                player.entity.SetRotationY(rotationY);
            }
        }
    }
}
